When a computing application is being debugged, evaluating certain expressions may cause unwanted and unexpected side effects or errors. Unless otherwise indicated, the term expression, as used herein, refers to any method, property, or other related function that either requires code to be run in the application being debugged or causes a change to the internal state of the application being debugged to successfully derive its value. These side effects may include, for example, changes in value to underlying data or changes in the state of the application itself. These side effects may disturb the debugging process by, for example, creating the appearance of non-existent bugs, or masking the appearance of existent bugs. These side effects may cause the application being debugged to hang or may even cause a complete crash of the application. In certain circumstances, side effects may cause an entire development environment to hang or crash.
A debugger typically cannot determine whether the evaluation of any particular expression will result in a side effect, but it can determine whether it has to execute a function in the process being debugged. Whenever the debugger has to call a function to evaluate an expression, there is a potential for a side effect to occur. However, depending on the expression being evaluated, a user may or may not be aware that a function is called. In particular, the evaluations of “properties” in modern languages such as C# or Java require a function call but are typically written such that they are less likely to result in side effects. By contrast, the evaluations of “member functions” are more likely to contain side effects. Additionally, there are other expressions, which are not properties or functions, that will, by definition, result in side effects. An example of this type of expression is the “i++” expression. The term implicit expression, as used herein, includes properties and other implicit function calls such as, for example, ToString( ). The term explicit expression, as used herein, refers to an expression that is either an obvious a function call or that obviously causes a side-effect.
When a user enters an expression into the debugger for the first time, the expression may be evaluated to determine its value. After an expression has already been evaluated, there are a number of actions which may cause the value of the expression to change. In particular, an expression's value may change when a user steps through a line of code in the debugger. Also, an expression's value may change when the context of the expression is changed by, for example, evaluating another expression, switching threads, changing a process, or switching call stack frames.
A limitation of conventional debuggers is that, upon the occurrence of one of these actions, they will automatically reevaluate the expression so that the value of the expression does not become stale. The term stale, as used herein, refers to a value that is not necessarily incorrect but which is out of date and may no longer be accurate. One problem with the automatic reevaluation of expressions is that it may result in one or more of the side effects discussed above. If an expression is explicit, then its automatic reevaluation is particularly problematic because, as discussed above, explicit expressions are more likely to result in side effects than are implicit expressions. Accordingly, there is a need in the art for a debugger that does not automatically reevaluate all expressions. Also, the value of expressions that do not involve function evaluations or other side-effects can become stale. For example, if an expression represents a variable that has a value, the user could step to a function or alternate scope that doesn't contain that variable. At that point, the value of the variable being viewed becomes stale. The expression's value will remain stale until its value can be successfully refreshed to be a non-error, or the user explicitly forces it to be refreshed. In prior implementations, an error string would typically be shown indicating that the expression is no longer valid in the new scope. In other words, the new value would be shown as an error.